<script lang="ts">
import { t } from "@transifex/native";
import { getContext } from "svelte";

import {
  asKilograms,
  asLiters,
  CddaData,
  i18n,
  normalizeDamageInstance,
  singular,
  singularName,
} from "../data";
import ThingLink from "./ThingLink.svelte";
import type {
  Harvest,
  Monster,
  MonsterGroup,
  Resistances,
  SpecialAttack as SpecialAttackT,
} from "../types";
import ItemSymbol from "./item/ItemSymbol.svelte";
import SpecialAttack from "./monster/SpecialAttack.svelte";
import Spoiler from "../Spoiler.svelte";
import ColorText from "./ColorText.svelte";
import ItemTable from "./item/ItemTable.svelte";

const _context = "Monster";

export let item: Monster;

let data = getContext<CddaData>("data");

function monsterArmor(armor: Resistances): Record<string, number> {
  if (armor) {
    const ret: Record<string, number> = {};
    for (const damageType of data.allDamageTypes()) {
      let value = armor[damageType.id];
      if (!value && damageType.derived_from) {
        const [derived_from, multiplier] = damageType.derived_from;
        value = armor[derived_from] * multiplier;
      }
      if (value) ret[damageType.id] = value;
    }
    return ret;
  }
  return {};
}

// prettier-ignore
function difficulty(mon: Monster): number {
  const {
    melee_skill = 0,
    melee_dice = 0,
    melee_damage = [],
    melee_dice_sides: melee_sides = 0,
    dodge: sk_dodge = 0,
    diff: difficulty_base = 0,
    special_attacks = [],
    emit_fields = [],
    hp,
    speed = 0,
    attack_cost = 100,
    morale = 0,
    aggression: agro = 0,
    vision_day = 40,
    vision_night = 1
  } = mon
  const normalizedMeleeDamage = normalizeDamageInstance(melee_damage)
  const melee_dmg_total = normalizedMeleeDamage.reduce((acc, { amount = 0, damage_multiplier = 1, constant_damage_multiplier = 1 }) => acc + amount * damage_multiplier * constant_damage_multiplier, 0)
  let armor_diff = 3
  for (const [damageTypeId, amount] of Object.entries(monsterArmor(mon.armor ?? {}))) {
    const damageType = data.byIdMaybe("damage_type", damageTypeId)
    if (damageType?.mon_difficulty)
      armor_diff += amount
  }
  const irrelevantAttacks = ["PARROT", "PARROT_AT_DANGER", "GRAZE", "EAT_CROP", "EAT_FOOD", "EAT_CARRION"]
  const id = (a: SpecialAttackT): string => Array.isArray(a) ? a[0] : "id" in a ? a.id : ""
  const relevantSpecialAttacks = special_attacks.filter(a => !irrelevantAttacks.includes(id(a)))
  let difficulty = ( melee_skill + 1 ) * melee_dice * ( melee_dmg_total + melee_sides ) * 0.04 +
               ( sk_dodge + 1 ) * armor_diff * 0.04 +
               ( difficulty_base + relevantSpecialAttacks.length + 8 * emit_fields.length );
  difficulty = Math.floor(difficulty);
  difficulty *= ( (hp ?? 1) + speed - attack_cost + ( morale + agro ) * 0.1 ) * 0.01 +
                ( vision_day + 2 * vision_night ) * 0.01;
  return Math.max(1, Math.floor(difficulty));
}

function difficultyDescription(diff: number) {
  if (diff < 3) {
    return i18n.__("<color_light_gray>Minimal threat.</color>");
  } else if (diff < 10) {
    return i18n.__("<color_light_gray>Mildly dangerous.</color>");
  } else if (diff < 20) {
    return i18n.__("<color_light_red>Dangerous.</color>");
  } else if (diff < 30) {
    return i18n.__("<color_red>Very dangerous.</color>");
  } else if (diff < 50) {
    return i18n.__("<color_red>Extremely dangerous.</color>");
  }
  return i18n.__("<color_red>Fatally dangerous!</color>");
}

function damage(mon: Monster) {
  let {
    melee_dice = 0,
    melee_dice_sides = 0,
    melee_damage = [],
    melee_cut,
  } = mon;
  const du = normalizeDamageInstance(melee_damage);
  if (melee_cut) {
    du.push({
      damage_type: "cut",
      amount: melee_cut,
    });
  }
  //melee_damage = melee_damage ?? [ { damage_type: "bash", amount: `${melee_dice}d${melee_dice_sides}` } ]
  return (
    `${melee_dice}d${melee_dice_sides} ${singularName(
      data.byIdMaybe("damage_type", "bash") ?? { id: "bash" }
    )}` +
    du
      .map(
        (u) =>
          ` + ${u.amount} ${singularName(
            data.byIdMaybe("damage_type", u.damage_type) ?? {
              id: u.damage_type,
            }
          )}`
      )
      .join("")
  );
}

// From mtype.h. See also https://github.com/CleverRaven/Cataclysm-DDA/blob/master/doc/JSON_FLAGS.md#monsters
// prettier-ignore
const mon_flag_descriptions: Record<string, string> = {
  SEES: "它可以看见你（并且会逃跑或跟随）",
  HEARS: "它可以听见你",
  GOODHEARING: "比大多数怪物更会追逐声音",
  SMELLS: "它可以闻到你",
  KEENNOSE: "敏锐的嗅觉",
  STUMBLES: "移动时会蹒跚",
  WARM: "温血动物",
  NOHEAD: "不能爆头！",
  HARDTOSHOOT: "远程攻击时体型小一级，但不小于 creature_size::tiny",
  GRABS: "它的攻击可能会抓住我们！",
  BASHES: "撞开门",
  DESTROYS: "撞毁墙壁等",
  BORES: "几乎可以钻穿任何东西",
  POISON: "食用有毒",
  VENOM: "攻击可能使玩家中毒",
  BADVENOM: "攻击可能使玩家严重中毒",
  PARALYZE: "攻击可能用毒液麻痹玩家",
  WEBWALK: "不会破坏蜘蛛网",
  DIGS: "挖地",
  CAN_DIG: "可以挖掘和行走",
  FLIES: "可以飞行（飞越水面等）",
  AQUATIC: "仅限于水中",
  SWIMS: "将水视为50移动点地形",
  ATTACKMON: "攻击其他怪物",
  ANIMAL: "就动物共情特质而言，是“动物”",
  PLASTIC: "在很大程度上吸收物理伤害",
  SUNDEATH: "在充足的阳光下死亡",
  ELECTRIC: "电击未武装的攻击者",
  ACIDPROOF: "免疫酸性伤害",
  ACIDTRAIL: "留下一道酸液痕迹",
  SHORTACIDTRAIL: "留下间歇性的酸液痕迹",
  FIREPROOF: "免疫火焰伤害",
  SLUDGEPROOF: "忽略污泥痕迹的效果",
  SLUDGETRAIL: "移动时会留下污泥陷阱痕迹",
  COLDPROOF: "免疫寒冷伤害",
  FIREY: "燃烧物体并且免疫火焰",
  QUEEN: "当它死亡时，当地的同类也会开始死亡",
  ELECTRONIC: "例如机器人；受EMP爆炸和其他东西影响",
  FUR: "屠宰时可能产生毛皮",
  LEATHER: "屠宰时可能产生皮革",
  WOOL: "屠宰时可能产生羊毛",
  BONES: "屠宰时可能产生骨头和筋腱；如果与POISON标记结合，则为受污染的骨头，如果与HUMAN标记结合，则为人类骨骼",
  FAT: "屠宰时可能产生脂肪；如果与POISON标记结合，则为受污染的脂肪",
  CONSOLE_DESPAWN: "当附近的控制台被成功破解时消失",
  IMMOBILE: "不移动（例如炮塔）",
  ID_CARD_DESPAWN: "当在附近的控制台上使用科学ID卡时消失",
  RIDEABLE_MECH: "一种可骑乘的机甲，在被骑乘前无法移动。",
  MILITARY_MECH: "一种为军事用途而设计的可骑乘机甲。",
  MECH_RECON_VISION: "这种机甲为你提供红外夜视功能。",
  MECH_DEFENSIVE: "这种机甲为你提供全面的保护。",
  HIT_AND_RUN: "近战攻击后逃跑数回合",
  GUILT: "杀死它会让你感到内疚",
  PAY_BOT: "你可以付钱让这个机器人暂时成为你的朋友",
  HUMAN: "只要它活着，它就是一个活生生的人",
  NO_BREATHE: "生物不会溺水，并且不受气体、烟雾或毒物伤害",
  FLAMMABLE: "怪物会着火、燃烧并将火势蔓延到附近的物体",
  REVIVES: "怪物尸体会在短时间内复活",
  CHITIN: "屠宰时可能产生甲壳质",
  VERMIN: "已弃用的标记，用于标记“讨厌的”或“场景”怪物，现在用于防止加载相同的怪物。",
  NOGIB: "受到巨大伤害死亡时，生物不会留下碎块/肉块。",
  LARVA: "生物是幼虫。目前用于处理碎块和血液。",
  ARTHROPOD_BLOOD: "迫使怪物流出淋巴液。",
  ACID_BLOOD: "使怪物渗出酸液。很有趣！死亡时不会自动溶解在酸液池中。",
  BILE_BLOOD: "使怪物渗出胆汁。",
  ABSORBS: "消耗其移动经过的物体以获得额外生命值。",
  ABSORBS_SPLITS: "消耗其移动经过的物体以获得额外生命值。如果获得足够的额外生命值，它会生成一个自身的复制品。",
  CBM_CIV: "屠宰时可能产生一个普通的CBM或一个动力CBM。",
  CBM_POWER: "屠宰时可能产生一个动力CBM，与MF_CBM_wev无关。",
  CBM_SCI: "屠宰时可能从bionics_sci中产生一个仿生装置。",
  CBM_OP: "屠宰时可能从bionics_op中产生一个仿生装置，并且能量存储为mk 2。",
  CBM_TECH: "屠宰时可能从bionics_tech中产生一个仿生装置。",
  CBM_SUBS: "屠宰时可能从bionics_subs中产生一个仿生装置。",
  FILTHY: "它掉落的任何衣物都会很脏。",
  FISHABLE: "它可以被钓鱼。",
  GROUP_BASH: "可以聚集在障碍物旁并合力将其摧毁的怪物。",
  SWARMS: "喜欢聚集在一起形成松散群体的怪物",
  GROUP_MORALE: "在朋友附近时更勇敢的怪物",
  INTERIOR_AMMO: "怪物将弹药储存在体内，发射时无需装填。防止在禁用时掉落弹药。",
  CLIMBS: "可以攀爬某些地形和家具的怪物",
  PACIFIST: "从不使用近战攻击的怪物，可用于让它们在不攻击玩家的情况下使用抓取",
  PUSH_MON: "可以将生物推开的怪物",
  PUSH_VEH: "可以将车辆推开的怪物",
  NIGHT_INVISIBILITY: "在光线不足的情况下隐形的怪物",
  REVIVES_HEALTHY: "复活时，此怪物拥有完整的生命值和速度",
  NO_NECRO: "此怪物无法被死灵法师复活。它仍然会自行复活。",
  PATH_AVOID_DANGER: "此怪物会绕过某些危险而不是穿过它们。",
  PATH_AVOID_DANGER_1: "此怪物会绕过某些危险而不是穿过它们。",
  PATH_AVOID_DANGER_2: "此怪物会绕过大多数危险而不是穿过它们。",
  PATH_AVOID_FIRE: "此怪物会绕过与热相关的危险而不是穿过它们。",
  PATH_AVOID_FALL: "此怪物会绕过悬崖而不是从悬崖上掉下去。",
  PRIORITIZE_TARGETS: "此怪物会根据目标的危险等级优先选择目标",
  NOT_HALLU: "玩家产生幻觉时不会出现的怪物",
  CATFOOD: "喂食猫粮后，此怪物会变得友好。",
  CATTLEFODDER: "喂食牲畜饲料后，此怪物会变得友好。",
  BIRDFOOD: "喂食鸟食后，此怪物会变得友好。",
  CANPLAY: "如果它是宠物，可以和它玩耍。",
  PET_MOUNTABLE: "驯服后，此怪物可以被骑乘。",
  PET_HARNESSABLE: "驯服后，此怪物可以被套上挽具。",
  DOGFOOD: "喂食狗粮后，此怪物会变得友好。",
  MILKABLE: "此怪物可以产奶。",
  SHEARABLE: "此怪物可以剪毛。",
  NO_BREED: "即使有繁殖数据，此怪物也不会繁殖",
  PET_WONT_FOLLOW: "驯服后，此怪物不会自动跟随玩家。",
  DRIPS_NAPALM: "此怪物移动时偶尔会滴下凝固汽油",
  DRIPS_GASOLINE: "此怪物移动时偶尔会滴下汽油",
  ELECTRIC_FIELD: "此怪物周围环绕着一个电场，会点燃附近的可燃液体",
  LOUDMOVES: "即使在飞行时，此怪物发出的移动噪音也好像响亮了约2个级别。",
  CAN_OPEN_DOORS: "此怪物可以开门。",
  STUN_IMMUNE: "此怪物免疫眩晕效果",
  DROPS_AMMO: "此怪物掉落弹药。不应为使用伪弹药的怪物设置此项。",
  INSECTICIDEPROOF: "尽管由虫肉制成，此怪物仍免疫杀虫剂",
  RANGED_ATTACKER: "此怪物拥有任何类型的远程攻击",
  CORNERED_FIGHTER: "如果敌人将其追至近战范围，此生物将停止逃跑并反击。",
  SMALL_HIDER: "这种小型怪物可以躲在床、冰箱和灌木丛等家具下面或后面。",
  CAN_BE_CULLED: "如果它是宠物，可以被宰杀。",
  EATS: "此生物有一个胃容量（在其怪物json中定义），进食时会填满，并随时间消化食物。",
  WATER_CAMOUFLAGE: "如果在水中，即使在光天化日之下，在（当前感知，如果角色具有侦察熟练度则+基础感知）格的距离内保持隐形。怪物从日间视野和夜间视野范围中较低者看到它。如果它在水下而观察者不在水下，也可以使其在深水或跨z轴时更难被看到。",
  NOT_HALLUCINATION: "玩家产生幻觉时此怪物不会出现。",
  PARALYZE_VENOM: "此怪物可以施加10分钟的麻痹效果。",
  HAS_MIND: "具有智慧和理性能力（例如，米戈、三尖树、半机械人等）。",
};

// prettier-ignore
const trigger_descriptions: Record<string, string> = {
  FIRE: "如果在3格内有火，则触发，效果强度等于火焰场强度的5倍。",
  FRIEND_ATTACKED: "如果怪物看到同类型的另一个怪物受到攻击，则触发；强度 = 15。",
  FRIEND_DIED: "如果怪物看到同类型的另一个怪物死亡，则触发；强度 = 15。",
  HURT: "当怪物受伤时触发，强度等于 1 + (伤害 / 3)。",
  MEAT: "附近有肉或尸体。",
  PLAYER_CLOSE: "当潜在敌人在5格范围内时触发。",
  PLAYER_WEAK: "如果潜在敌人的剩余生命值低于70%，则怪物攻击性提高 10 - (剩余生命值百分比 / 10)",
  PLAYER_NEAR_BABY: "如果**玩家**进入其后代（由其繁殖数据中的baby_monster字段定义）3格范围内，则怪物攻击性增加8，士气增加4",
  SOUND: "不是实际的触发器，攻击性高于10且士气为0的怪物会朝向声源徘徊，士气低于0的怪物会远离声源徘徊1回合（如果它们具有GOODHEARING标记，则为6回合）。",
  STALK: "如果攻击性 > 5，则每回合有20%的几率触发，怪物攻击性提高1。",
  HOSTILE_SEEN: "对于每个可以看到的潜在敌人，攻击性增加/士气降低0-2之间的随机数量，最高可达20点攻击性。",
  MATING_SEASON: "如果潜在敌人在5格范围内，并且季节与怪物的交配季节（由其繁殖数据中的baby_flags字段定义）相同，则攻击性增加3。"
}

let materials = item.material ?? [];

let deathDrops = data.flatDeathDrops(item.id);

let harvest: Harvest | undefined = item.harvest
  ? data.byId("harvest", item.harvest)
  : undefined;

let dissect: Harvest | undefined = item.dissect
  ? data.byId("harvest", item.dissect)
  : undefined;

function flattenGroup(mg: MonsterGroup): string[] {
  const results = new Set<string>();
  if (mg.default) results.add(mg.default);
  for (const m of mg.monsters ?? []) {
    if (m.monster) results.add(m.monster);
    if (m.group)
      for (const n of flattenGroup(data.byId("monstergroup", m.group)))
        results.add(n);
  }
  return [...results];
}

let upgrades =
  item.upgrades && (item.upgrades.into || item.upgrades.into_group)
    ? {
        ...item.upgrades,
        monsters: item.upgrades.into
          ? [item.upgrades.into]
          : item.upgrades.into_group
          ? flattenGroup(data.byId("monstergroup", item.upgrades.into_group))
          : [],
      }
    : null;
</script>

<h1><ItemSymbol {item} /> {singularName(item)}</h1>
<section>
  <dl>
    {#if item.fromMod}
      <dt>来源模组</dt>
      <dd>{item.fromMod}</dd>
    {/if}
    {#if item.bodytype}
      <dt>{t("Body Type", { _context })}</dt>
      <dd>{item.bodytype}</dd>
    {/if}
    {#if item.species && item.species.length}
      <dt>{t("Species", { _context })}</dt>
      <dd>{[item.species ?? []].flat().join(", ")}</dd>
    {/if}
    <dt>{t("Volume")}</dt>
    <dd>{asLiters(item.volume ?? 0)}</dd>
    <dt>{t("Weight")}</dt>
    <dd>{asKilograms(item.weight ?? 0)}</dd>
    {#if materials.length}
      <dt>{t("Material")}</dt>
      <dd>
        <ul class="comma-separated">
          {#each materials as id}
            <li><ThingLink type="material" {id} /></li>
          {/each}
        </ul>
      </dd>
    {/if}
    <dt>{t("Difficulty", { _context })}</dt>
    <dd>
      {difficulty(item)}
      (<ColorText
        text={difficultyDescription(difficulty(item))}
        fgOnly={true} />)
    </dd>
  </dl>
  {#if item.description}
    <p style="color: var(--cata-color-gray)">{singular(item.description)}</p>
  {/if}
</section>
<Spoiler spoily={item.id === "mon_dragon_dummy"}>
  <div class="side-by-side">
    <section>
      <h1>{t("Attack", { _context, _comment: "Section heading" })}</h1>
      <dl>
        <dt>{t("Speed", { _context })}</dt>
        <dd>{item.speed ?? 0}</dd>
        <dt>{t("Melee Skill", { _context })}</dt>
        <dd>{item.melee_skill ?? 0}</dd>
        <dt>{t("Damage", { _context })}</dt>
        <dd>{damage(item)}</dd>
        {#if item.special_attacks}
          <dt>{t("Special Attacks", { _context })}</dt>
          <dd>
            <ul class="no-bullets">
              {#each item.special_attacks as special_attack}
                <li>
                  {#if Array.isArray(special_attack) && special_attack[0] && data.byIdMaybe("monster_attack", special_attack[0])}
                    <ThingLink type="monster_attack" id={special_attack[0]} />
                  {:else}
                    <SpecialAttack {special_attack} />
                  {/if}
                </li>
              {/each}
            </ul>
          </dd>
        {/if}
      </dl>
    </section>
    <section>
      <h1>{t("Defense", { _context, _comment: "Section heading" })}</h1>
      <dl style="flex: 1">
        <dt>{t("HP", { _context })}</dt>
        <dd>{item.hp}</dd>
        {#if item.regenerates}
          <dt>{t("Regenerates", { _context })}</dt>
          <dd>{item.regenerates} hp/turn</dd>
        {/if}
        <dt>{t("Dodge", { _context })}</dt>
        <dd>{item.dodge ?? 0}</dd>
        <dt>{t("Armor", { _context })}</dt>
        {#if item.armor}
          <dd>
            <dl>
              {#each Object.entries(monsterArmor(item.armor)) as [damageTypeId, value]}
                {@const damageType = data.byIdMaybe(
                  "damage_type",
                  damageTypeId
                )}
                {#if value}
                  <dt>{singularName(damageType ?? { id: damageTypeId })}</dt>
                  <dd>{value.toFixed(1)}</dd>
                {/if}
              {/each}
            </dl>
          </dd>
        {:else}
          <dd>
            <dl>
              <dt>{t("Bash", { _context: "Damage Type" })}</dt>
              <dd>{item.armor_bash ?? 0}</dd>
              <dt>{t("Cut", { _context: "Damage Type" })}</dt>
              <dd>{item.armor_cut ?? 0}</dd>
              <dt>{t("Stab", { _context: "Damage Type" })}</dt>
              <dd>
                {item.armor_stab ?? Math.floor((item.armor_cut ?? 0) * 0.8)}
              </dd>
              <dt>{t("Ballistic", { _context: "Damage Type" })}</dt>
              <dd>{item.armor_bullet ?? 0}</dd>
              <dt>{t("Acid", { _context: "Damage Type" })}</dt>
              <dd>
                {item.armor_acid ?? Math.floor((item.armor_cut ?? 0) * 0.5)}
              </dd>
              <dt>{t("Heat", { _context: "Damage Type" })}</dt>
              <dd>{item.armor_fire ?? 0}</dd>
            </dl>
          </dd>
        {/if}
        {#if item.special_when_hit}
          <dt>{t("When Hit", { _context })}</dt>
          <dd>{item.special_when_hit[0]} ({item.special_when_hit[1]}%)</dd>
        {/if}
      </dl>
    </section>
  </div>
  <section>
    <h1>{t("Behavior", { _context, _comment: "Section heading" })}</h1>
    <dl>
      <dt
        title="Monsters with high aggression are more likely to be hostile. Ranges from -100 to 100">
        {t("Aggression", { _context })}
      </dt>
      <dd>{item.aggression ?? 0}</dd>
      <dt title="Morale at spawn. Monsters with low morale will flee.">
        {t("Morale", { _context })}
      </dt>
      <dd>{item.morale ?? 0}</dd>
      <dt>{t("Vision Range", { _context })}</dt>
      <dd>
        {item.vision_day ?? 40} ({t("day", { _context })}) / {item.vision_night ??
          1} ({t("night", { _context })})
      </dd>
      <dt>{t("Default Faction", { _context })}</dt>
      <dd>{item.default_faction}</dd>
      {#if item.anger_triggers?.length}
        <dt>{t("Anger Triggers", { _context })}</dt>
        <dd>
          <ul class="comma-separated">
            {#each item.anger_triggers as t}
              <li><abbr title={trigger_descriptions[t]}>{t}</abbr></li>
            {/each}
          </ul>
        </dd>
      {/if}
      {#if item.placate_triggers?.length}
        <dt>{t("Placate Triggers", { _context })}</dt>
        <dd>
          <ul class="comma-separated">
            {#each item.placate_triggers as t}
              <li><abbr title={trigger_descriptions[t]}>{t}</abbr></li>
            {/each}
          </ul>
        </dd>
      {/if}
      {#if item.fear_triggers?.length}
        <dt>{t("Fear Triggers", { _context })}</dt>
        <dd>
          <ul class="comma-separated">
            {#each item.fear_triggers as t}
              <li><abbr title={trigger_descriptions[t]}>{t}</abbr></li>
            {/each}
          </ul>
        </dd>
      {/if}
      {#if item.flags?.length}
        <dt>{t("Flags")}</dt>
        <dd>
          <ul class="comma-separated">
            {#each item.flags ?? [] as flag}
              <li><abbr title={mon_flag_descriptions[flag]}>{flag}</abbr></li>
            {/each}
          </ul>
        </dd>
      {/if}
      {#if item.death_function}
        <dt>{t("On Death", { _context })}</dt>
        <dd>
          {#if item.death_function.effect?.id && data.byIdMaybe("SPELL", item.death_function.effect.id)}
            {singularName(data.byId("SPELL", item.death_function.effect.id))} ({singular(
              data.byId("SPELL", item.death_function.effect.id).description
            )})
          {:else}
            {item.death_function.effect?.id ??
              item.death_function.corpse_type ??
              "NORMAL"}
          {/if}
        </dd>
      {/if}
      {#if upgrades}
        <dt>{t("Upgrades Into", { _context })}</dt>
        <dd>
          <ul class="comma-separated or">
            <!-- prettier-ignore -->
            {#each upgrades.monsters as mon}<li><ThingLink type="monster" id={mon} /></li>{/each}
          </ul>
          {#if upgrades.age_grow}
            {t("in {days} {days, plural, =1 {day} other {days}}", {
              _context,
              days: upgrades.age_grow,
            })}
          {:else if upgrades.half_life}
            {t(
              "with a half-life of {half_life} {half_life, plural, =1 {day} other {days}}",
              { _context, half_life: upgrades.half_life }
            )}
          {/if}
        </dd>
      {/if}
    </dl>
  </section>
  {#if deathDrops.size}
    <ItemTable loot={deathDrops} heading={t("Drops")} />
  {/if}
  {#if harvest && (harvest.entries ?? []).length}
    <section>
      <h1>{t("Butchering Results", { _context })}</h1>
      <ul>
        {#each harvest.entries as harvest_entry}
          {#if (harvest_entry.type && data.byIdMaybe("harvest_drop_type", harvest_entry.type)?.group) || harvest_entry.type === "bionic_group"}
            {#each data.flattenTopLevelItemGroup(data.byId("item_group", harvest_entry.drop)) as { id, prob }}
              <li>
                <ItemSymbol item={data.byId("item", id)} />
                <ThingLink type="item" {id} /> ({(prob * 100).toFixed(2)}%)
              </li>
            {/each}
          {:else}
            <li>
              <ItemSymbol item={data.byId("item", harvest_entry.drop)} />
              <ThingLink type="item" id={harvest_entry.drop} />
            </li>
          {/if}
        {/each}
      </ul>
    </section>
  {/if}
  {#if dissect && (dissect.entries ?? []).length}
    <section>
      <h1>{t("Dissection Results", { _context })}</h1>
      <ul>
        {#each dissect.entries as harvest_entry}
          {#if (harvest_entry.type && data.byId("harvest_drop_type", harvest_entry.type)?.group) || harvest_entry.type === "bionic_group"}
            {#each data
              .flattenTopLevelItemGroup(data.byId("item_group", harvest_entry.drop))
              .sort((a, b) => b.prob - a.prob) as { id, prob }}
              <li>
                <ItemSymbol item={data.byId("item", id)} />
                <ThingLink type="item" {id} /> ({(prob * 100).toFixed(2)}%)
              </li>
            {/each}
          {:else}
            <li>
              <ItemSymbol item={data.byId("item", harvest_entry.drop)} />
              <ThingLink type="item" id={harvest_entry.drop} />
            </li>
          {/if}
        {/each}
      </ul>
    </section>
  {/if}
</Spoiler>
